<template>
  <div>
    <div :class="`audio-zj ${(disabled || mock) && 'audio-disabled'} ${isbg ? '' : 'isbg'}`">
      <div class="a1">
        <el-image :src="playImg" v-show="isPlay" class="a-icon" @click="playClick"></el-image>
        <el-image :src="pauseImg" v-show="!isPlay" class="a-icon" @click="playClick"></el-image>
        <div class="t-bottom">
          <el-slider
            v-model="progress"
            :show-tooltip="false"
            :max="timeCount"
            :disabled="disabled || mock"
            class="jindu"
            @input="proChange"
            @change="proUp"
          />
          <span class="already-time">{{ startTime }}/</span>
          <span class="total-time">{{ endTime }}</span>
        </div>
      </div>
      <audio
        ref="audioPlayer"
        class="audioPlayer"
        @timeupdate="timeupdate"
        :src="audioUrl"
        @loadeddata="onLoad"
        @ended="onEnded"
        controls
      ></audio>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, onMounted, onUnmounted } from 'vue';
import playImg from '@/assets/chat/audio/play.png';
import pauseImg from '@/assets/chat/audio/pause.png';
import { useAudioStore } from '@/store/modules/audio';

const props = defineProps({
  url: String,
  speed: String,
  noiseSuppression: Boolean,
  disabled: Boolean,
  isbg: String,
  mock: {
    type: Boolean,
    default: false,
  },
  playData: {
    type: Object,
    default: () => ({}),
  },
  res: {
    type: String,
    default: '',
  },
});

const emit = defineEmits(['playClick', 'closePanel', 'onLoad', 'onEnded', 'closeBox', 'downloadAudio']);

const audioStore = useAudioStore();
const audioPlayer = ref<any>();
const audioUrl = ref(props.url);
const progress = ref(0);
const timeCount = ref(0);
const startTime = ref('00:00');
const endTime = ref('00:00');
const isPlay = ref(false);
const time = ref();
const time1 = ref();
const run = ref(false);
const ended = ref(false);
const needPlay = ref(false);
const isDown = ref(false);

watch(
  () => props.url,
  newVal => {
    audioUrl.value = newVal;
    endTime.value = '00:00';
    playAudio();
  },
);

watch(
  () => props.speed,
  newVal => {
    if (audioPlayer.value) {
      audioPlayer.value.playbackRate = newVal;
    }
  },
);

watch(
  () => props.noiseSuppression,
  newVal => {
    if (audioPlayer.value) {
      audioPlayer.value.noiseSuppression = newVal;
    }
  },
);

watch(
  () => props.playData,
  newVal => {
    if (!newVal.isPlay) {
      progress.value = 0;
      isPlay.value = false;
      startTime.value = '00:00';
      audioPlayer.value?.pause();
      clearInterval(time.value);
      clearInterval(time1.value);
    }
  },
  { deep: true },
);

const proChange = () => {
  if (isDown.value) {
    clearInterval(time.value);
    clearInterval(time1.value);
    audioPlayer.value.pause(progress.value / 10);
  }
};

const proUp = () => {
  isDown.value = false;
  audioPlayer.value.currentTime = progress.value / 10;
  audioPlayer.value.play();
  clearInterval(time.value);
  clearInterval(time1.value);
  isPlay.value = true;
  time1.value = setInterval(() => {
    progress.value++;
    startTime.value = secondToTime(progress.value / 10);
  }, 100);
};

const closeBtn = () => {
  playClick();
  emit('closeBox');
};

const playClick = () => {
  if (endTime.value == '00:00') {
    return;
  }
  if (!audioUrl.value || props.disabled || props.mock) return;

  // 暂停其他音频
  if (audioPlayer.value) {
    audioStore.pauseAllExcept(audioPlayer.value);
  }

  startOrStop();
};

const startOrStop = () => {
  isPlay.value = !isPlay.value;
  emit('playClick', { ...props.playData, isPlay: isPlay.value, res: props.res });

  if (isPlay.value) {
    audioPlayer.value?.play();
    time.value = setInterval(() => {
      progress.value++;
      startTime.value = secondToTime(progress.value / 10);
    }, 100);
  } else {
    audioPlayer.value?.pause();
    clearInterval(time.value);
    clearInterval(time1.value);
  }
};

const onPlay = () => {
  if (isPlay.value) return false;
  clearInterval(time.value);
  clearInterval(time1.value);
  isPlay.value = true;
  emit('playClick', { ...props.playData, isPlay: isPlay.value, res: props.res });

  if (isPlay.value) {
    audioPlayer.value.play();
    time.value = setInterval(() => {
      progress.value++;
      startTime.value = secondToTime(progress.value / 10);
    }, 100);
  }
};

const playAudio = () => {
  progress.value = 0;
  isPlay.value = false;
  startTime.value = '00:00';
  audioPlayer.value?.pause();
  clearInterval(time.value);
  clearInterval(time1.value);

  const total = setInterval(() => {
    if (audioPlayer.value?.readyState > 0) {
      timeCount.value = Math.round(audioPlayer.value.duration) * 10;
      endTime.value = secondToTime(audioPlayer.value.duration);
      clearInterval(total);
    }
  }, 100);
};

const timeupdate = () => {
  if (run.value) return;
  run.value = true;
  emit('closePanel');
};

const onLoad = () => {
  ended.value = false;
  emit('onLoad');
  timeCount.value = Math.round(audioPlayer.value!.duration) * 10;
  endTime.value = secondToTime(audioPlayer.value!.duration);
};

const onEnded = () => {
  isPlay.value = false;
  clearInterval(time.value);
  clearInterval(time1.value);
  progress.value = 0;
  startTime.value = secondToTime(progress.value);
  emit('onEnded');
  ended.value = true;
  needPlay.value = false;
};

const secondToTime = (val: number) => {
  if (!isFinite(val)) return '0:00';

  val = Math.round(val);

  // 计算分钟，不补零
  const minutes = Math.floor(val / 60);

  // 计算秒数，补零
  const seconds = val % 60;
  const secondsStr = seconds < 10 ? `0${seconds}` : seconds;

  return `${minutes}:${secondsStr}`;
};

// 下载
const downloadMp3 = () => {
  emit('downloadAudio');
};

// 注册音频实例
onMounted(() => {
  if (audioPlayer.value) {
    audioStore.register(audioPlayer.value);
    // 监听外部暂停事件
    audioPlayer.value.addEventListener('force-pause', () => {
      isPlay.value = false;
      clearInterval(time.value);
      clearInterval(time1.value);
    });

    // 初始化音频时长
    if (audioUrl.value) {
      playAudio();
    }
  }
});

onUnmounted(() => {
  if (audioPlayer.value) {
    audioStore.unregister(audioPlayer.value);
  }
});
</script>

<style lang="scss">
.audio-zj {
  .jindu {
    .el-slider__button {
      background: #f68842 !important;
      background-color: #f68842;
      border: solid 2px #f68842;
      width: 11px;
      height: 11px;
    }
    .el-slider__bar {
      background-color: #f68842;
      height: 3px;
    }
    .el-slider__runway {
      height: 3px;
    }
  }
}
</style>
<style lang="scss" scoped>
.audio-zj {
  width: 100%;
  display: flex;
  align-items: center;
  box-sizing: border-box;
  .a1 {
    width: 100%;
    display: flex;
    align-items: center;
    .a-icon {
      display: block;
      width: 20px;
      height: 20px;
      cursor: pointer;
      &.active {
        width: 38px;
      }
    }
  }
  .t-bottom {
    width: 100%;
    display: flex;
    align-items: center;
    // margin-left: 19px;
    .jindu {
      margin: 0 13px;
    }
    .already-time {
      font-weight: 400;
      font-size: 14px;
      color: #6a6a6a;
      line-height: 20px;
      // margin-left: 19px;
      width: 35px;
      margin-right: 2px;
    }
    .total-time {
      font-weight: 400;
      font-size: 14px;
      color: #6a6a6a;
      line-height: 22px;
    }
  }

  .audioPlayer {
    display: none;
  }
}
.isbg {
  background: #ffffff;
  // border-radius: 24px;
  // border: 1px solid #e9e9e9;
  // padding: 8px 16px;
}
.audio-disabled {
  cursor: not-allowed;
  .a1 {
    cursor: not-allowed;
    .a-icon {
      cursor: not-allowed;
      opacity: 0.5;
    }
  }
}
.audio-operation {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 4px;

  img {
    cursor: pointer;
  }
}
</style>
